package com.rabbiter.hospital.controller;

import com.rabbiter.hospital.pojo.Admin;
import com.rabbiter.hospital.pojo.Doctor;
import com.rabbiter.hospital.service.AdminService;
import com.rabbiter.hospital.service.DoctorService;
import com.rabbiter.hospital.service.OrderService;
import com.rabbiter.hospital.service.PatientService;
import com.rabbiter.hospital.utils.JwtUtil;
import com.rabbiter.hospital.utils.ResponseData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;


@RestController
@RequestMapping("admin")
public class AdminController {

    @Autowired
    private AdminService adminService;
    @Autowired
    private DoctorService doctorService;
    @Autowired
    private PatientService patientService;
    @Autowired
    private OrderService orderService;

    /**
     * 登录数据验证
     * 该方法通过接收管理员ID和密码，验证登录信息，并返回相应的响应数据
     * 使用了@RequestParam注解来绑定请求参数，确保参数名称与方法参数相匹配
     * 通过@ResponseBody注解将方法返回的Java对象转换为JSON格式的数据，直接响应给客户端
     * @param aId       管理员ID，用于识别管理员
     * @param aPassword 管理员密码，用于验证管理员身份
     * @return 返回一个ResponseData对象，包含操作结果和可能的附加信息，如登录成功时的token
     */
    @PostMapping("/login")
    @ResponseBody
    public ResponseData login(@RequestParam("aId") int aId, @RequestParam("aPassword") String aPassword) {
        // 调用AdminService的login方法尝试登录，如果登录成功，将返回Admin对象，否则返回null
        Admin admin = this.adminService.login(aId, aPassword);
        if (admin != null) {
            // 创建一个Map来存储管理员姓名和ID，用于生成JWT token
            Map<String, String> map = new HashMap<>();
            map.put("aName", admin.getAName());
            map.put("aId", String.valueOf(admin.getAId()));
            // 使用JwtUtil生成token
            String token = JwtUtil.getToken(map);
            // 将生成的token添加到map中，以便返回给客户端
            map.put("token", token);
            // 返回登录成功的结果，包含token等信息
            return ResponseData.success("登录成功", map);
        } else {
            // 如果登录验证失败，返回登录失败的结果，并提示错误原因
            return ResponseData.fail("登录失败，密码或账号错误");
        }
    }

    /**
     * 分页模糊查询所有医护人员信息
     * @param pageNumber 当前页码，用于分页查询
     * @param size       每页大小，即每页显示的记录数
     * @param query      模糊查询的关键字，用于根据关键字查询医护人员信息
     * @return ResponseData 包含医护人员信息和操作成功的状态码及提示信息
     */
    @RequestMapping("findAllDoctors")
    public ResponseData findAllDoctors(@RequestParam(value = "pageNumber") int pageNumber, @RequestParam(value = "size") int size, @RequestParam(value = "query") String query) {
        return ResponseData.success("返回医护人员信息成功", this.doctorService.findAllDoctors(pageNumber, size, query));
    }

    /**
     * 根据id查找医生
     * @param dId 医生的id，作为查找的依据
     * @return 包含查询结果的ResponseData对象，包括状态和数据
     */
    @RequestMapping("findDoctor")
    public ResponseData findDoctor(@RequestParam(value = "dId") int dId) {
        return ResponseData.success("查询医生成功", this.doctorService.findDoctor(dId));
    }

    /**
     * 增加医生信息
     * 该方法用于接收HTTP请求，将Doctor对象传递给服务层以添加新的医生信息
     * @param doctor 要添加的医生信息对象
     * @return 返回一个ResponseData对象，表示添加操作的结果
     */
    @RequestMapping("addDoctor")
    @ResponseBody
    public ResponseData addDoctor(Doctor doctor) {
        // 调用服务层方法添加医生信息，返回操作是否成功的布尔值
        Boolean bo = this.doctorService.addDoctor(doctor);
        // 根据操作结果返回相应的响应数据
        if (bo) {
            return ResponseData.success("增加医生信息成功");
        }
        return ResponseData.fail("增加医生信息失败！账号或已被占用");
    }

    /**
     * 删除医生信息
     * 通过HTTP请求调用此方法，以删除特定的医生信息
     * @param dId 医生的ID，用于标识要删除的医生
     * @return 返回一个ResponseData对象，包含操作结果和消息
     * 如果删除成功，返回成功消息
     * 如果删除失败，返回失败消息
     */
    @RequestMapping("deleteDoctor")
    public ResponseData deleteDoctor(@RequestParam(value = "dId") int dId) {
        // 执行删除医生操作
        Boolean bo = this.doctorService.deleteDoctor(dId);
        // 根据删除结果返回相应的响应数据
        if (bo) {
            return ResponseData.success("删除医生信息成功");
        }
        return ResponseData.fail("删除医生信息失败");
    }

    /**
     * 修改医生信息
     * 此方法用于更新医生的信息。接收到客户端的请求后，将新的医生信息对象作为参数，
     * 并调用医生服务中的modifyDoctor方法来更新数据库中的医生信息。
     * 参数:
     * - doctor: 需要修改的医生信息对象，包含了医生的所有信息字段。
     * 返回:
     * - ResponseData对象，包含操作结果信息。如果修改成功，返回成功消息。
     * bug: dState会自动更新为0
     * 注意：目前存在一个已知的问题（bug），即在修改医生信息时，医生的状态（dState）
     * 会自动重置为0，这可能是因为代码中没有正确处理dState字段的更新，
     * 或者是数据库操作中没有正确地保存dState的值。需要进一步检查和修复此问题。
     */
    @RequestMapping("modifyDoctor")
    @ResponseBody
    public ResponseData modifyDoctor(Doctor doctor) {
        this.doctorService.modifyDoctor(doctor);
        return ResponseData.success("修改医生信息成功");
    }

    /**
     * 分页模糊查询所有患者信息
     * 通过分页和模糊查询参数，返回一组患者信息
     * @param pageNumber 分页查询的页码
     * @param size       每页包含的患者记录数量
     * @param query      模糊查询的关键词
     * @return 包含患者信息的响应数据对象
     */
    @RequestMapping("findAllPatients")
    public ResponseData findAllPatients(@RequestParam(value = "pageNumber") int pageNumber, @RequestParam(value = "size") int size, @RequestParam(value = "query") String query) {
        // 返回分页查询到的患者信息列表
        return ResponseData.success("返回患者信息成功", this.patientService.findAllPatients(pageNumber, size, query));
    }

    /**
     * 删除患者信息
     * 通过HTTP请求调用此方法，以删除特定患者的记录
     * @param pId 患者的ID，用于标识要删除的患者记录
     * @return 返回一个ResponseData对象，包含操作状态和消息
     * 如果患者记录成功删除，则返回成功消息
     * 否则，返回失败消息
     */
    @RequestMapping("deletePatient")
    public ResponseData deletePatient(@RequestParam(value = "pId") int pId) {
        // 调用patientService中的deletePatient方法尝试删除患者信息
        Boolean bo = this.patientService.deletePatient(pId);
        // 根据删除结果返回相应的响应数据
        if (bo) {
            return ResponseData.success("删除患者信息成功");
        }
        return ResponseData.fail("删除患者信息失败");
    }

    /**
     * 分页模糊查询所有挂号信息
     * @param pageNumber 当前页码，用于分页查询
     * @param size       每页大小，即每页包含的挂号信息数量
     * @param query      搜索关键字，用于模糊查询
     * @return 包含挂号信息的响应数据对象，成功时包含状态码和消息，以及挂号信息列表
     * 该方法通过@RequestParam注解接收请求参数，调用orderService的findAllOrders方法进行分页和模糊查询，
     * 并使用ResponseData封装查询结果以JSON形式返回给前端。
     */
    @RequestMapping("findAllOrders")
    public ResponseData findAllOrders(@RequestParam(value = "pageNumber") int pageNumber, @RequestParam(value = "size") int size, @RequestParam(value = "query") String query) {
        return ResponseData.success("返回挂号信息成功", this.orderService.findAllOrders(pageNumber, size, query));
    }

    /**
     * 删除挂号信息
     * @param oId 病人的挂号ID
     * @return 返回操作结果的响应数据对象
     */
    @RequestMapping("deleteOrder")
    public ResponseData deleteOrder(@RequestParam(value = "oId") int oId) {
        // 调用orderService中的deleteOrder方法尝试删除指定的挂号信息
        Boolean bo = this.orderService.deleteOrder(oId);
        // 判断删除操作是否成功
        if (bo) {
            // 如果成功，返回成功消息
            return ResponseData.success("删除挂号信息成功");
        }
        // 如果失败，返回失败消息
        return ResponseData.fail("删除挂号信息失败");
    }

}
